﻿using System;
using System.Configuration;
using System.Data;
using System.Data.EntityClient;
using System.Data.Objects;
using System.Data.Objects.DataClasses;
using MobileCommissionManagement.Common;
using Enumerable = System.Linq.Enumerable;

namespace MobileCommissionManagement
{
    public class Controller
    {
        private readonly GlobalEntities _context;
        
        public Controller()
        {
            _context = new GlobalEntities(new EntityConnection(GetConnectionString("GlobalEntities")));
            _context.Connection.Open();
        }

        #region public Properties
        
        public ObjectQuery<Operadores> Operators { get { return _context.Operadores.OrderBy("it.Nome"); } }

        public ObjectQuery<Zonas> Zones { get { return _context.Zonas.OrderBy("it.Nome"); } }

        public ObjectQuery<Entidades> Entities { get { return _context.Entidades.OrderBy("it.Nome"); } }

        public ObjectQuery<TiposEntidade> EntityTypes { get { return _context.TiposEntidade.OrderBy("it.Nome"); } }
        
        #endregion Properties

        #region public event

        public event EventHandler<EventArgs> ZoneSaved;

        public event EventHandler<EventArgs> EntityTypeSaved;

        public event EventHandler<EventArgs> EntitySaved;

        #endregion

        #region Event Handlers

        private void OnZoneSaved()
        {
            EventHandler<EventArgs> zoneSaved = ZoneSaved;
            if (zoneSaved != null)
                zoneSaved(this, new EventArgs());
        }

        private void OnEntityTypeSaved()
        {
            EventHandler<EventArgs> entityTypeSaved = EntityTypeSaved;
            if (entityTypeSaved != null)
                entityTypeSaved(this, new EventArgs());
        }

        private void OnEntitySaved()
        {
            EventHandler<EventArgs> entitySaved = EntitySaved;
            if (entitySaved != null)
                entitySaved(this, new EventArgs());
        }

        #endregion Event Handlers

        #region Private Methods

        private static string GetConnectionString(string name)
        {
            foreach (ConnectionStringSettings connectionString in ConfigurationManager.ConnectionStrings)
                if (connectionString.Name == name)
                    return connectionString.ConnectionString;
            return string.Empty;
        }

        private Entidades GetEntity(long id)
        {
            ObjectQuery<Entidades> entities = _context.Entidades.Where("it.IdEntidade == @Id", new ObjectParameter("Id", id));
            return Enumerable.FirstOrDefault(entities);
        }

        #endregion Private Methods

        public bool Logon(string userName, string password)
        {            
            ObjectQuery<Utilizadores> users = _context.Utilizadores.Where("it.Nome == @Name and it.password == @Password",
                new ObjectParameter("Name", userName), new ObjectParameter("Password", password));
            return Enumerable.Any(users);
        }

        public void SaveZone(Zonas zone)
        {
            // Validate
            if (zone.EntityState == EntityState.Detached)
                _context.AddToZonas(zone);
            _context.SaveChanges();
            OnZoneSaved();
        }

        public void SaveEntityType(TiposEntidade entityType)
        {
            // Validate
            if (entityType.EntityState == EntityState.Detached)
                _context.AddToTiposEntidade(entityType);
            _context.SaveChanges();
            OnEntityTypeSaved();
        }
        
        public EntityCollection<EntidadeDetalhes> GetEntityDetails(int entityId)
        {
            Entidades entity = GetEntity(entityId);
            if(entity == null)
                return null;
            entity.EntidadeDetalhes.Load();
            return entity.EntidadeDetalhes;
        }

        public void SaveEntity(Entidades entity)
        {
            // Validate
            if (entity.EntityState == EntityState.Detached)
                _context.AddToEntidades(entity);
            foreach(EntidadeDetalhes entityDetail in entity.EntidadeDetalhes)
                if (entityDetail.EntityState == EntityState.Detached)
                    _context.AddToEntidadeDetalhes(entityDetail);
            _context.SaveChanges();
            OnEntitySaved();
        }

    }
}
